/* JavaLog - package tracker 
 * 
 * Copyright (C) 2009  Allyson Lima, Diego Pedro, Victor Freire
 * 
 * This program is free software: you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free Software 
 * Foundation, either version 3 of the License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful, but WITHOUT ANY
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
 * PARTICULAR PURPOSE.  See the GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License along with this 
 * program.  If not, see <http://www.gnu.org/licenses/>.
 */
package br.edu.ufcg.ccc.javalog.view;
import java.awt.Component;
import java.awt.Frame;
import java.awt.event.ActionEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Arrays;
import java.util.Set;

import javax.swing.AbstractAction;
import javax.swing.DefaultComboBoxModel;
import javax.swing.GroupLayout;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.LayoutStyle;
import javax.swing.ListModel;
import javax.swing.ListSelectionModel;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;

import br.edu.ufcg.ccc.javalog.controller.HeadquartersController;
import br.edu.ufcg.ccc.javalog.exceptions.HeadquartersControllerException;
import br.edu.ufcg.ccc.javalog.model.Franchise;
import br.edu.ufcg.ccc.javalog.model.Headquarters;
import br.edu.ufcg.ccc.javalog.model.Validator;


/**
* This code was edited or generated using CloudGarden's Jigloo
* SWT/Swing GUI Builder, which is free for non-commercial
* use. If Jigloo is being used commercially (ie, by a corporation,
* company or business for any purpose whatever) then you
* should purchase a license for each developer using Jigloo.
* Please visit www.cloudgarden.com for details.
* Use of Jigloo implies acceptance of these licensing terms.
* A COMMERCIAL LICENSE HAS NOT BEEN PURCHASED FOR
* THIS MACHINE, SO JIGLOO OR THIS CODE CANNOT BE USED
* LEGALLY FOR ANY CORPORATE OR COMMERCIAL PURPOSE.
*/
/**
 * Dialog for franchise selection.
 * 
 * @author Allyson Lima, Diego Pedro, Victor Freire
 * @version 08/11/09
 */
@SuppressWarnings("serial")
public class SearchFranchiseDialog extends JDialog {
	private static SearchFranchiseDialog dialog;
	private static Franchise selectedFranchise;
	private HeadquartersController headquartersController;
	
	private JLabel labelName;
	private JTextField textName;
	private JLabel labelCity;
	private AbstractAction actionOk;
	private AbstractAction actionSearchFranchise;
	private JList listFranchise;
	private JScrollPane scrollListFranchise;
	private AbstractAction actionCancel;
	private JButton buttonSelect;
	private JButton buttonCancel;
	private JButton buttonSearchFranchise;
	private JTextField textCity;
	private JLabel labelSearchFranchise;
	
	/**
	 * Set up and show this dialog. 
	 * @param frameComp which frame the dialog depends on
	 * @param locationComp null for the dialog to come up with its left corner in the center of the screen or the component on top of which the dialog should appear.
	 * @param headquarters the model to operate on
	 * @return the Franchise object if one was selected by the user, or null if no Franchise was selected
	 */
	public static Franchise showDialog(Component frameComp, Component locationComp, Headquarters headquarters) {
        Frame frame = JOptionPane.getFrameForComponent(frameComp);
        dialog = new SearchFranchiseDialog(frame, locationComp, headquarters);
        dialog.setVisible(true);
        return selectedFranchise;
    }

	/**
	* Auto-generated main method to display this JDialog
	*/
	public static void main(String[] args) {
		SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				SearchFranchiseDialog inst = new SearchFranchiseDialog();
				inst.setLocationRelativeTo(null);
				inst.setVisible(true);
			}
		});
	}
		
	private SearchFranchiseDialog() {
		super();
		initGUI();
	}
	
	/**
	 * Creates the dialog for the specified headquarters model object.
	 * @param frameComp which frame the dialog depends on
	 * @param locationComp null for the dialog to come up with its left corner in the center of the screen or the component on top of which the dialog should appear.
	 * @param headquarters the model to view
	 */
	private SearchFranchiseDialog(Frame frame, Component locationComp, Headquarters headquarters) {
		super(frame, "Escolha uma franquia", true);
		initGUI();
		setLocationRelativeTo(locationComp);
		Validator.validateObject(headquarters, new IllegalArgumentException("null headquarters received"));
		headquartersController = new HeadquartersController(headquarters);
		buttonSearchFranchise.doClick();
		selectedFranchise = null;
	}
			
	private void initGUI() {
		try {
			GroupLayout thisLayout = new GroupLayout((JComponent)getContentPane());
			getContentPane().setLayout(thisLayout);
			setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);

			{
				labelName = new JLabel();
				labelName.setText("Nome:");
			}
			{
				textName = new JTextField();
			}
			{
				labelSearchFranchise = new JLabel();
				labelSearchFranchise.setText("Dados da Franquia");
				labelSearchFranchise.setFont(new java.awt.Font("Tahoma",1,12));
			}
			{
				labelCity = new JLabel();
				labelCity.setText("Cidade:");
			}
			{
				textCity = new JTextField();
			}
			{
				buttonSearchFranchise = new JButton();
				buttonSearchFranchise.setText("Pesquisar");
				buttonSearchFranchise.setAction(getActionSearchFranchise());
			}
			{
				buttonCancel = new JButton();
				buttonCancel.setText("Cancelar");
				buttonCancel.setAction(getActionCancel());
			}
			{
				buttonSelect = new JButton();
				buttonSelect.setText("OK");
				buttonSelect.setAction(getActionOk());
			}
			thisLayout.setVerticalGroup(thisLayout.createSequentialGroup()
			.addContainerGap()
			.addComponent(labelSearchFranchise, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE)
			.addGap(20)
			.addGroup(thisLayout.createParallelGroup(GroupLayout.Alignment.BASELINE)
			    .addComponent(textName, GroupLayout.Alignment.BASELINE, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE)
			    .addComponent(labelName, GroupLayout.Alignment.BASELINE, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE))
			.addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED)
			.addGroup(thisLayout.createParallelGroup(GroupLayout.Alignment.BASELINE)
			    .addComponent(textCity, GroupLayout.Alignment.BASELINE, GroupLayout.PREFERRED_SIZE, 21, GroupLayout.PREFERRED_SIZE)
			    .addComponent(labelCity, GroupLayout.Alignment.BASELINE, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE))
			.addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED)
			.addComponent(buttonSearchFranchise, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE)
			.addGap(20)
			.addComponent(getScrollListFranchise(), 0, 151, Short.MAX_VALUE)
			.addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
			.addGroup(thisLayout.createParallelGroup(GroupLayout.Alignment.BASELINE)
			    .addComponent(buttonSelect, GroupLayout.Alignment.BASELINE, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE)
			    .addComponent(buttonCancel, GroupLayout.Alignment.BASELINE, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE))
			.addContainerGap());
		thisLayout.setHorizontalGroup(thisLayout.createSequentialGroup()
				.addContainerGap()
				.addGroup(thisLayout.createParallelGroup()
				    .addGroup(thisLayout.createSequentialGroup()
				        .addGroup(thisLayout.createParallelGroup()
				            .addComponent(labelCity, GroupLayout.Alignment.LEADING, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE)
				            .addGroup(GroupLayout.Alignment.LEADING, thisLayout.createSequentialGroup()
				                .addComponent(labelName, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE)
				                .addGap(6)))
				        .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
				        .addGroup(thisLayout.createParallelGroup()
				            .addComponent(textCity, GroupLayout.Alignment.LEADING, 0, 380, Short.MAX_VALUE)
				            .addComponent(textName, GroupLayout.Alignment.LEADING, 0, 380, Short.MAX_VALUE)))
				    .addGroup(GroupLayout.Alignment.LEADING, thisLayout.createSequentialGroup()
				        .addGroup(thisLayout.createParallelGroup()
				            .addComponent(labelSearchFranchise, GroupLayout.Alignment.LEADING, GroupLayout.PREFERRED_SIZE, 198, GroupLayout.PREFERRED_SIZE)
				            .addGroup(GroupLayout.Alignment.LEADING, thisLayout.createSequentialGroup()
				                .addComponent(buttonSearchFranchise, GroupLayout.PREFERRED_SIZE, 142, GroupLayout.PREFERRED_SIZE)
				                .addGap(56)))
				        .addGap(0, 49, Short.MAX_VALUE)
				        .addComponent(buttonSelect, GroupLayout.PREFERRED_SIZE, 63, GroupLayout.PREFERRED_SIZE)
				        .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED)
				        .addComponent(buttonCancel, GroupLayout.PREFERRED_SIZE, 108, GroupLayout.PREFERRED_SIZE))
				    .addComponent(getScrollListFranchise(), GroupLayout.Alignment.LEADING, 0, 429, Short.MAX_VALUE))
				.addContainerGap());
			pack();
			this.setSize(461, 377);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	private AbstractAction getActionCancel() {
		if(actionCancel == null) {
			actionCancel = new AbstractAction("Cancelar", null) {
				public void actionPerformed(ActionEvent evt) {
					dispose();
				}
			};
			actionCancel.putValue(javax.swing.Action.MNEMONIC_KEY, new Integer(java.awt.event.KeyEvent.VK_C));
		}
		return actionCancel;
	}
	
	private JScrollPane getScrollListFranchise() {
		if(scrollListFranchise == null) {
			scrollListFranchise = new JScrollPane();
			scrollListFranchise.setViewportView(getListFranchise());
		}
		return scrollListFranchise;
	}
	
	private JList getListFranchise() {
		if(listFranchise == null) {
			ListModel listFranchiseModel = 
				new DefaultComboBoxModel(
						new String[] { "Digite as informações da franquia desejada acima." });
			listFranchise = new JList();
			listFranchise.setModel(listFranchiseModel);
			listFranchise.setEnabled(false);
			listFranchise.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
			listFranchise.addMouseListener(new MouseAdapter() {
				public void mouseClicked(MouseEvent evt) {
					listFranchiseMouseClicked(evt);
				}
			});
		}
		return listFranchise;
	}
	
	private AbstractAction getActionSearchFranchise() {
		if(actionSearchFranchise == null) {
			actionSearchFranchise = new AbstractAction("Pesquisar", null) {
				public void actionPerformed(ActionEvent evt) {
					String name = textName.getText(),
						   city = textCity.getText();
					
					listFranchise.setEnabled(false);
					
					if(headquartersController == null) {
						JOptionPane.showMessageDialog(SearchFranchiseDialog.this, "Falha ao tentar acessar dados.", "Erro", JOptionPane.ERROR_MESSAGE);
						listFranchise.setListData(new String[] { "Falha ao tentar acessar dados."});
						return;
					}
					
					try {
						Set<Franchise> franchises = headquartersController.listFranchises(name, city);
						if(franchises.isEmpty()) {
							listFranchise.setListData(new String[] {"Nenhum franquia encontrada. Tente uma busca menos específica."});
						}
						else {
							Object[] franchiseArray = franchises.toArray();
							Arrays.sort(franchiseArray);
							listFranchise.setListData(franchiseArray);
							listFranchise.setEnabled(true);
						}
					} 
					catch(HeadquartersControllerException e) {
						JOptionPane.showMessageDialog(SearchFranchiseDialog.this, e.getMessage(), "Erro", JOptionPane.ERROR_MESSAGE);
					}
					
				}
			};
			actionSearchFranchise.putValue(javax.swing.Action.MNEMONIC_KEY, new Integer(java.awt.event.KeyEvent.VK_P));
		}
		return actionSearchFranchise;
	}
	
	private AbstractAction getActionOk() {
		if(actionOk == null) {
			actionOk = new AbstractAction("OK", null) {
				public void actionPerformed(ActionEvent evt) {
					if(!listFranchise.isEnabled() || listFranchise.getSelectedValue() == null) {
						JOptionPane.showMessageDialog(SearchFranchiseDialog.this, "Nenhuma franquia foi selecionada.", "Erro", JOptionPane.ERROR_MESSAGE);
					}
					else {
						selectedFranchise = (Franchise)listFranchise.getSelectedValue();
						dispose();
					}
				}
			};
			actionOk.putValue(javax.swing.Action.MNEMONIC_KEY, new Integer(java.awt.event.KeyEvent.VK_O));
		}
		return actionOk;
	}
	
	/**
	 * Return the franchise selected by the user. Null if no valid selection has been made.
	 * @return
	 */
	public static Franchise getValue() {
		return selectedFranchise;
	}
	
	
	/**
	* This method should return an instance of this class which does 
	* NOT initialize it's GUI elements. This method is ONLY required by
	* Jigloo if the superclass of this class is abstract or non-public. It 
	* is not needed in any other situation.
	 */
	public static Object getGUIBuilderInstance() {
		return new SearchFranchiseDialog(Boolean.FALSE);
	}
	
	/**
	 * This constructor is used by the getGUIBuilderInstance method to
	 * provide an instance of this class which has not had it's GUI elements
	 * initialized (ie, initGUI is not called in this constructor).
	 */
	public SearchFranchiseDialog(Boolean initGUI) {
		super();
	}
	
	/**
	 * Event for selecting an entry with a double click.
	 * @param evt the mouse event
	 */
	private void listFranchiseMouseClicked(MouseEvent evt) {
		if (evt.getClickCount() == 2) {
            buttonSelect.doClick(); 
        }
	}

}
